package com.lcf.framework.handler;

import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.lcf.framework.config.TenantIgnoreTableConfig;
import com.lcf.framework.resolver.TableEntityResolver;
import com.lcf.framework.utils.UserUtils;
import jakarta.annotation.Resource;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.springframework.stereotype.Component;

/**
 * 描述：租户处理器
 *
 * @author lcf
 * @since 2025/2/27 11:57
 */
@Component
public class TenantHandler implements TenantLineHandler {
    @Resource
    private TenantIgnoreTableConfig tenantIgnoreTableConfig;
    @Resource
    private TableEntityResolver tableEntityResolver;

    @Override
    public Expression getTenantId() {
        return new LongValue(UserUtils.getTenantId());
    }

    /**
     * 根据表名判断是否忽略拼接多租户条件
     * 默认都要进行解析并拼接多租户条件
     * Params:
     * tableName – 表名
     * Returns:
     * 是否忽略, true:表示忽略，false:需要解析并拼接多租户条件
     *
     * @param tableName 表名
     */
    @Override
    public boolean ignoreTable(String tableName) {
        for (String ignoreTable : tenantIgnoreTableConfig.getTables()) {
            if (tableName.equals(ignoreTable)) {
                return true;
            }
        }

        //临时忽略租户id
        if (MybatisTenantContext.get()) {
            return true;
        }

        //根据表名去找对应实体类判断是否包含租户id
        return !tableEntityResolver.hasTenantIdByTableName(tableName);
    }

    /**
     * 临时忽略租户id
     *
     * @author lcf
     */
    public static class MybatisTenantContext {
        private static final ThreadLocal<Boolean> TENANT_CONTEXT_THREAD_LOCAL = ThreadLocal.withInitial(() -> Boolean.FALSE);

        public static Boolean get() {
            return TENANT_CONTEXT_THREAD_LOCAL.get();
        }

        public static void ignore() {
            TENANT_CONTEXT_THREAD_LOCAL.set(true);
        }

        public static void clear() {
            TENANT_CONTEXT_THREAD_LOCAL.remove();
        }
    }
}
